using System;
using System.Linq;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using WalkingTec.Mvvm.Core;
using WalkingTec.Mvvm.Core.Extensions;
using WalkingTec.Mvvm.Mvc;
using HengTong.ViewModel.Hr.SysHrJobAssignmentRequestBillEntryVms;
using HengTong.Model.Db.Hr.Bill;
using HengTong.Model.Db.Hr;
using Microsoft.EntityFrameworkCore;
using TiaoTaoHelper.Models;
using TiaoTaoHelper.Wtm.Attributes;
using TiaoTaoHelper.Wtm.Models;


namespace HengTong.Areas.Hr.Controllers
{
    [Area("Hr")]
    [AuthorizeJwtWithCookie]
    [ActionDescription("岗位分配明细")]
    [ApiController]
    [Route("api/SysHrJobAssignmentRequestBillEntry")]
    public partial class SysHrJobAssignmentRequestBillEntryController : BaseApiController
    {
        [ActionDescription("Sys.Search")]
        [HttpPost("Search")]
        public IActionResult Search(SysHrJobAssignmentRequestBillEntrySearcher searcher)
        {
            if (ModelState.IsValid)
            {
                var vm = Wtm.CreateVM<SysHrJobAssignmentRequestBillEntryListVm>(passInit: true);
                vm.Searcher = searcher;
                return Ok(vm.GetJsonForApi());
            }
            else
            {
                return BadRequest(ModelState.GetErrorJson());
            }
        }

        [ActionDescription("Sys.Get")]
        [HttpGet("{id}")]
        public SysHrJobAssignmentRequestBillEntryVm Get(string id)
        {
            var vm = Wtm.CreateVM<SysHrJobAssignmentRequestBillEntryVm>(id);
            return vm;
        }

        [ActionDescription("Sys.Create")]
        [HttpPost("Add")]
        [PreventDuplicateSubmit]
        public async Task<IActionResult> Add(SysHrJobAssignmentRequestBillEntryVm vm)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState.GetErrorJson());
            }
            else
            {
                await vm.DoAddAsync();
                if (!ModelState.IsValid)
                {
                    return BadRequest(ModelState.GetErrorJson());
                }
                else
                {
                    return Ok(vm.Entity);
                }
            }
        }

        [ActionDescription("Sys.Edit")]
        [PreventDuplicateSubmit]
        [HttpPut("Edit")]
        public async Task<IActionResult> Edit(SysHrJobAssignmentRequestBillEntryVm vm)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState.GetErrorJson());
            }
            else
            {
                await vm.DoEditAsync(false);
                if (!ModelState.IsValid)
                {
                    return BadRequest(ModelState.GetErrorJson());
                }
                else
                {
                    return Ok(vm.Entity);
                }
            }
        }

        [HttpPost("BatchDelete")]
        [ActionDescription("Sys.Delete")]
        [PreventDuplicateSubmit]
        public IActionResult BatchDelete(string[] ids)
        {
            var vm = Wtm.CreateVM<SysHrJobAssignmentRequestBillEntryBatchVm>();
            if (ids != null && ids.Any())
            {
                vm.Ids = ids;
            }
            else
            {
                return Ok();
            }

            if (!ModelState.IsValid || !vm.DoBatchDelete())
            {
                return BadRequest(ModelState.GetErrorJson());
            }
            else
            {
                return Ok(ids.Count());
            }
        }


        [ActionDescription("Sys.Export")]
        [HttpPost("ExportExcel")]
        public IActionResult ExportExcel(SysHrJobAssignmentRequestBillEntrySearcher searcher)
        {
            var vm = Wtm.CreateVM<SysHrJobAssignmentRequestBillEntryListVm>();
            vm.Searcher = searcher;
            vm.SearcherMode = ListVMSearchModeEnum.Export;
            return vm.GetExportData();
        }

        [ActionDescription("Sys.CheckExport")]
        [HttpPost("ExportExcelByIds")]
        public IActionResult ExportExcelByIds(string[] ids)
        {
            var vm = Wtm.CreateVM<SysHrJobAssignmentRequestBillEntryListVm>();
            if (ids != null && ids.Any())
            {
                vm.Ids = new List<string>(ids);
                vm.SearcherMode = ListVMSearchModeEnum.CheckExport;
            }

            return vm.GetExportData();
        }

        [ActionDescription("Sys.DownloadTemplate")]
        [HttpGet("GetExcelTemplate")]
        public IActionResult GetExcelTemplate()
        {
            var vm = Wtm.CreateVM<SysHrJobAssignmentRequestBillEntryImportVm>();
            var qs = new Dictionary<string, string>();
            foreach (var item in Request.Query.Keys)
            {
                qs.Add(item, Request.Query[item]);
            }

            vm.SetParms(qs);
            var data = vm.GenerateTemplate(out string fileName);
            return File(data, "application/vnd.ms-excel", fileName);
        }

        [ActionDescription("Sys.Import")]
        [HttpPost("Import")]
        public ActionResult Import(SysHrJobAssignmentRequestBillEntryImportVm vm)
        {
            if (vm != null && (vm.ErrorListVM.EntityList.Count > 0 || !vm.BatchSaveData()))
            {
                return BadRequest(vm.GetErrorJson());
            }
            else
            {
                return Ok(vm?.EntityList?.Count ?? 0);
            }
        }


        [HttpGet("GetSysPersons")]
        public ActionResult GetSysPersons()
        {
            return Ok(DC.Set<SysPerson>().GetSelectListItems(Wtm, x => x.Name));
        }

        [HttpGet("GetSysJobPositions")]
        public ActionResult GetSysJobPositions()
        {
            return Ok(DC.Set<SysJobPosition>().GetSelectListItems(Wtm, x => x.Name));
        }

        [HttpGet("GetSysGroups")]
        public ActionResult GetSysGroups()
        {
            return Ok(DC.Set<SysGroup>().Where(x => !x.IsDisabled).OrderBy(x => x.Order ?? 99.99m)
                .Select(x => new { Value = x.ID, Text = x.GroupName }).ToList());
        }

        [HttpGet("GetSysOrgs")]
        public ActionResult GetSysOrgs()
        {
            return Ok(DC.Set<SysOrg>().OrderBy(x => x.Order ?? 99.99m).Select(x => new { Value = x.ID, Text = x.Name })
                .ToList());
        }

        [HttpGet("GetSysHrJobAssignmentRequestBills")]
        public ActionResult GetSysHrJobAssignmentRequestBills()
        {
            return Ok(DC.Set<SysHrJobAssignmentRequestBill>().GetSelectListItems(Wtm, x => x.BillCode));
        }

        /// <summary>
        /// 批量分配公司、部门、岗位
        /// </summary>
        /// <param name="ids">明细ID列表</param>
        /// <param name="orgId">公司ID，可选</param>
        /// <param name="groupId">部门ID，可选</param>
        /// <param name="jobPositionId">岗位ID，可选</param>
        /// <returns>操作结果</returns>
        [ActionDescription("批量分配岗位（人事/部门）")]
        [HttpPost("BatchAssignPositions")]
        [PreventDuplicateSubmit]
        public async Task<Result<int>> BatchAssignPositions([FromBody] BatchAssignPositionsRequest request)
        {
            if (request?.Ids == null || !request.Ids.Any())
                return new Result<int>("请选择要分配的数据");

            if (!request.OrgId.HasValue && !request.GroupId.HasValue && !request.JobPositionId.HasValue)
                return new Result<int>("请至少选择一个分配项（公司、部门或岗位）");

            // Dept 模式：校验主表流程状态必须为“已完成”
            if (request.Mode == AssignMode.Dept)
            {
                var validateMsg = await ValidateDeptModeAsync(request.Ids);
                if (!string.IsNullOrEmpty(validateMsg))
                    return new Result<int>(validateMsg);
            }

            var vm = Wtm.CreateVM<SysHrJobAssignmentRequestBillEntryBatchVm>();
            vm.Ids = request.Ids;

            // Hr：不同步账号信息；Dept：同步账号信息
            var syncUserAccount = request.Mode == AssignMode.Dept;

            return await vm.BatchAssignPositionsAsync(
                request.OrgId, request.GroupId, request.JobPositionId, syncUserAccount);
        }

        // 私有校验：Dept 模式下明细所属主表流程状态必须为“已完成”
        private async Task<string> ValidateDeptModeAsync(IEnumerable<string> ids)
        {
            var idList = new List<Guid>();
            foreach (var s in ids)
            {
                if (Guid.TryParse(s, out var gid)) idList.Add(gid);
            }

            if (!idList.Any())
                return "未找到有效的岗位申请明细";

            var entries = await DC.Set<SysHrJobAssignmentRequestBillEntry>()
                .Include(e => e.JobAssignment)
                .Where(e => idList.Contains(e.ID))
                .ToListAsync();

            if (!entries.Any())
                return "未找到有效的岗位申请明细";

            var invalidBills = entries
                .Where(e => e.JobAssignment == null || e.JobAssignment.WorkflowStatus != WorkflowStatus.已完成)
                .Select(e => e.JobAssignment?.BillCode ?? e.JobAssignmentId.ToString())
                .Distinct()
                .ToList();

            return invalidBills.Any()
                ? $"以下单据流程状态不是已完成：{string.Join(", ", invalidBills)}"
                : null;
        }

        // 在 SysHrJobAssignmentRequestBillEntryController 类内新增接口
        [ActionDescription("部门批量分岗位")]
        [HttpPost("DeptBatchAssignPositions")]
        [PreventDuplicateSubmit]
        public async Task<Result<int>> DeptBatchAssignPositions([FromBody] BatchAssignPositionsRequest request)
        {
            if (request?.Ids == null || !request.Ids.Any())
            {
                return new Result<int>("请选择要分配的数据");
            }

            if (!request.OrgId.HasValue && !request.GroupId.HasValue && !request.JobPositionId.HasValue)
            {
                return new Result<int>("请至少选择一个分配项（公司、部门或岗位）");
            }

            var idList = request.Ids.Select(Guid.Parse).ToList();

            var entries = await DC.Set<SysHrJobAssignmentRequestBillEntry>()
                .Include(e => e.JobAssignment)
                .Where(e => idList.Contains(e.ID))
                .ToListAsync();

            if (!entries.Any())
            {
                return new Result<int>("未找到有效的岗位申请明细");
            }

            // 校验：每条明细所属主表流程状态必须为“已完成”
            var invalidBills = entries
                .Where(e => e.JobAssignment == null || e.JobAssignment.WorkflowStatus != WorkflowStatus.已完成)
                .Select(e => e.JobAssignment?.BillCode ?? e.JobAssignmentId.ToString())
                .Distinct()
                .ToList();

            if (invalidBills.Any())
            {
                return new Result<int>($"以下单据流程状态不是已完成：{string.Join(", ", invalidBills)}");
            }

            // 仅更新子表（复用已有批量分配逻辑）
            var vm = Wtm.CreateVM<SysHrJobAssignmentRequestBillEntryBatchVm>();
            vm.Ids = request.Ids;
            return await vm.DeptBatchAssignPositionsAsync(request.OrgId, request.GroupId, request.JobPositionId);
        }


        /// <summary>
        /// 批量分配岗位请求模型
        /// </summary>
        public class BatchAssignPositionsRequest
        {
            /// <summary>
            /// 明细ID列表
            /// </summary>
            public string[] Ids { get; set; }

            /// <summary>
            /// 公司ID，可选
            /// </summary>
            public Guid? OrgId { get; set; }

            /// <summary>
            /// 部门ID，可选
            /// </summary>
            public Guid? GroupId { get; set; }

            /// <summary>
            /// 岗位ID，可选
            /// </summary>
            public Guid? JobPositionId { get; set; }

            /// <summary>
            ///  分配模式：Hr（人事分配）或 Dept（部门分配）
            /// </summary>
            public AssignMode Mode { get; set; } = AssignMode.Hr;
        }

        public enum AssignMode
        {
            Hr = 0, // 人事批量
            Dept = 1 // 部门批量
        }
    }
}